<template>
  <el-select-v2
    v-model="vValue"
    v-bind="attrs"
    :disabled="disabled"
    :remote-method="remoteMethod"
    :loading="loading"
    collapse-tags
    collapse-tags-tooltip
    :options="selectList"
    @blur="itemEvent('blur', $event)"
    @focus="itemEvent('focus', $event)"
    @change="itemEvent('change', $event)"
    style="width: 100%"
  >
  </el-select-v2>
</template>

<script setup>
import _ from 'lodash';
import { vModelValue } from '@/utils/hooks.js';
import { apiMethods } from '@/utils/http.js';

const attrs = useAttrs();
const props = defineProps({
  modelValue: {
    type: [String, Array, Number],
  },
  options: {
    // 下拉值集合
    type: Array,
    default: () => [],
  },
  filterKey: {
    // 下拉值label和value的取值字段名
    type: Object,
    default: () => ({
      label: 'label',
      value: 'value',
    }),
  },
  requestUrl: {
    // 下拉接口
    type: String,
    default: '',
  },
  tierData: {
    // 调用接口获取数据的层级关系
    type: String,
    default: '',
  },

  isInitData: {
    // 初始化是否加载数据
    type: Boolean,
    default: true,
  },
  // 传参
  params: {
    type: Object,
    default: () => ({}),
  },
  axiosMethod: {
    // 请求方式
    type: String,
    default: 'post',
  },
  remoteQueryKey: {
    // 远程传参key
    type: String,
    default: 'param',
  },
  cb: {
    // 获取列表之后回调
    type: Function,
  },
  isRemote: {
    // 是否远程
    type: Boolean,
    default: false,
  },
  addAll: {
    // 在前端添加All选项并选中，值为''
    type: String,
    default: '',
  },
});
const emits = defineEmits(['update:modelValue', 'itemEvent']);
const { newValue: key } = vModelValue(props, emits);
let vValue = ref(key);

let requestList = ref([]);
let loading = ref(false);
let remoteParams = ref({});

onMounted(() => {
  if (props.isInitData && props.requestUrl) getDataList();
});

// 下拉值过滤
const selectList = computed(() => {
  let list = [];
  if (props.options?.length) {
    list = [...props.options];
  } else if (props.requestUrl) {
    list = requestList.value;
  }
  if (list?.length) {
    const { label, value } = props.filterKey;
    list = list.map(item => ({
      label: item[label],
      value: item[value],
      disabled: !!item.disabled,
    }));
  }
  if (props.addAll) {
    list = [{ value: '', label: props.addAll }, ...list];
  }
  return list;
});

// 请求接口
async function getDataList(callback) {
  let res = await apiMethods[props.axiosMethod](props.requestUrl, {
    ...props.params,
    ...remoteParams.value,
  });
  requestList.value = [];
  let arr = null;
  if (props.tierData) {
    let tierArr = props.tierData.split('.');
    tierArr.forEach(item => {
      arr = arr ? arr[item] : res[item];
    });
  } else {
    arr = res.data.data || [];
  }
  requestList.value = [...arr];
  props.cb && props.cb(arr);
  callback && callback();
}

// 是否禁用
const disabled = computed(() => {
  return attrs.disabledFn && _.isFunction(attrs.disabledFn)
    ? attrs.disabledFn(attrs)
    : attrs.disabled || false;
});

// 事件
function itemEvent(eventName, $event) {
  let [selectRow] = requestList.value.filter(item => item[props.filterKey.value] == $event);
  emits('itemEvent', {
    eventName,
    ...attrs,
    value: $event,
    prop: attrs.prop,
    selectRow,
  });
}

// 远程
function remoteMethod(query) {
  if (!props.isRemote) return;
  if (query) {
    loading.value = true;
    remoteParams.value[props.remoteQueryKey] = query;
    getDataList(() => {
      loading.value = false;
    });
  } else {
    requestList.value = [];
  }
}

watch(
  () => props.requestUrl,
  url => {
    if (url) getDataList();
  }
);
</script>
